#	Compile and link .c, .obj and/or .lib files for Windows NT, Release 2.1.d
#	Copyright (c) 1992-1993 by Hamilton Laboratories.  All rights reserved.

#	If CPU == MIPS, either the old MIPS compiler or the new hybrid Microsoft/
#	MIPS compiler may be used.  By default on NTVersion < 404 (not March beta),
#	the old MIPS compiler is used; on NTVersion >= 404, the new compiler is
#	the default.  You may explicitly specify old or new using the -old or
#	-new options.

#	If CPU == ALPHA, either the old Alpha compiler or the new hybrid Microsoft/
#	DEC compiler may be used.  By default on NTVersion < 404 (not March beta),
#	the old ALPHA compiler is used; on NTVersion >= 404, the new compiler is
#	the default.  You may explicitly specify old or new using the -old or
#	-new options.

#	By default, cl will compile and link using the following options:

#		i386 Compile:		-c -Od -Zi -W4 -DNT -Di386=1 -D_X86_=1 -DWIN32
#								-Dend=EndOfData

#		MIPS Compile:
#			using MIPS:		-c -std -O -o $i:b.obj -EL -DNT -DMIPS=1 -D_MIPS_=1
#								-DWIN32 -Dend=EndOfData
#			using new MS:	-c -Od -Zi -W4 -DNT -DMIPS=1 -D_MIPS_=1 -DWIN32
#								-Dend=EndOfData

#		ALPHA Compile:
#			using DEC:		-c -std -G 0 -o $i:b.obj -checkstack 4096 -01 -EL
#								-Dend=EndOfData -DNT -DALPHA=1 -DWIN32 -excpt -DDEVL=1
#								-I<include directories>
#			using new MS:	-c -Od -Zi -W4 -DNT -DALPHA=1 -D_ALPHA_=1 -DWIN32
#								-Dend=EndOfData -D__stdcall= -D_cdecl=

#		Link:					-subsystem:console -entry:mainCRTStartup -debug:full
#								-debugtype:both

#	All the output is filtered thru ferr which filters out nuisance
#	error messages such as the warnings about no modules extracted from
#	a given .lib file or about assignments inside conditional tests.
#	The list of nuisance messages is kept in skip file pointed to by the
#	skip variable.  If skip isn't set or doesn't point to a real file, cl.csh
#	wil attempt to look for a skip file in the same directory with this
#	script.

if (! $?skip || ! -e $skip) then
	#	Look for the filter file in the same directory with this cl.csh script.
	set s = `whereis cl.csh`
	if ($#s && -e $s[0]:h\skip) then
		set skip = $s[0]:h\skip
		alias ferr fgrep -vqf $skip
	else
		echo -2 Warning:  Output filter file not found!  No filtering will be done.
		alias ferr cat
	end
else
	alias ferr	fgrep -vqf $skip
end

proc cl(args)
	local i, j, ^
			debug, c_only, O_opt, options, ^
			c_files, obj_files, lib_files, exe, ldir, stdlibs, ^
			use_old_cc, linker

	switch (CPU)
		case "MIPS":
			@ use_old_cc = NTVersion < 404
			@ O_opt = ""
			break
		case "ALPHA":
			@ use_old_cc = NTVersion < 404
			@ O_opt = "-O1"
			break
		default:
			@ O_opt = "-Od"
	end

	@ c_only = 0
	for i = 0 to $#args - 1 do
		@ j = substr(args[i], 1, 1)
		if (j == '-' || j == '/') then
			if (substr(args[i], 2) == 'c') then
				@ c_only = 1
			else
				if (substr(args[i], 2, 1) == 'O') then
					set Oopt = $args[i]
				else
					if (CPU != "i386" && substr(args[i], 2) == "old") then
						@ use_old_cc = 1
					else
						if (CPU != "i386" && substr(args[i], 2) == "new") then
							@ use_old_cc = 0
						else
							set options = $options $args[i]
						end
					end
				end
			end
		else
			switch ($args[i]:e)
				case 'c':
					set c_files = $c_files $args[i]
					set obj_files = $obj_files $args[i]:b.obj
					break
				case 'obj':
					set obj_files = $obj_files $args[i]
					break
				case 'exe':
					set exe = $args[i]
					break
				case 'lib':
				default:
					set lib_files = $lib_files $args[i]
			end
		end
	end

	#	Run the compile step on each .c file.
	(switch (CPU)
		case "MIPS":
			if (use_old_cc) then
				foreach i ($c_files)
					echo cc -c -std -O -o $i:b.obj -EL -DNT -DMIPS=1 -D_MIPS_=1 ^
							-DWIN32 -Dend=EndOfData $options $i
					cc -c -std -O -o $i:b.obj -EL -DNT -DMIPS=1 -D_MIPS_=1 ^
							-DWIN32 -Dend=EndOfData $options $i
					if ($status) return
					echo mip2coff $i:b.obj
					mip2coff $i:b.obj
					if ($status) return
				end
			else
				foreach i ($c_files)
					echo mcl -c $O_opt -Zi -W4 -DNT -DMIPS=1 -D_MIPS_=1 -DWIN32 ^
							-Dend=EndOfData $options $i
					mcl -c $O_opt -Zi -W4 -DNT -DMIPS=1 -D_MIPS_=1 -DWIN32 ^
							-Dend=EndOfData $options $i
					if ($status) return
				end
			end
			break

		case "ALPHA":
			if (use_old_cc) then
				#	Alpha compiler doesn't handle the INCLUDE environment variable
				#	properly -- it has to be passed on the command line.
				set Inc = -I$INCLUDE:gs/;/ -I/
				if (NTVersion < 404) set options = -EL -excpt -DDEVL=1 $options
				foreach i ($c_files)
					echo acc -c -std -G 0 -o $i:b.obj -checkstack 4096			^
							$O_opt -Dend=EndOfData -DNT -DALPHA=1 -D_ALPHA_=1	^
							-DWIN32 $options $Inc $i
					acc -c -std -G 0 -o $i:b.obj -checkstack 4096				^
							$O_opt -Dend=EndOfData -DNT -DALPHA=1 -D_ALPHA_=1	^
							-DWIN32 $options $Inc $i
					if ($status) return
					echo a2coff $i:b.obj
					a2coff $i:b.obj
					if ($status) return
				end
			else
				foreach i ($c_files)
					echo claxp -c $O_opt -Zi -W4 -DNT -DALPHA=1 -D_ALPHA_=1	^
							-DWIN32 -Dend=EndOfData -D__stdcall= -D_cdecl=		^
							$options $i
					claxp -c $O_opt -Zi -W4 -DNT -DALPHA=1 -D_ALPHA_=1 -DWIN32 ^
							-Dend=EndOfData -D__stdcall= -D_cdecl= $options $i
					if ($status) return
				end
			end
			break

		default:
			foreach i ($c_files)
				echo cl386 -c $O_opt -Zi -W4 -DNT -Di386=1 -D_X86_=1 -DWIN32 ^
						-Dend=EndOfData $options $i
				cl386 -c $O_opt -Zi -W4 -DNT -Di386=1 -D_X86_=1 -DWIN32 ^
						-Dend=EndOfData $options $i
				if ($status) return
			end
	end

	if (! $c_only) then

		#	If no .exe file was specified, name the output to match the
		#	first .c or .obj file on the command line.
		if (exe == '') then
			@ exe = $#c_files == 0 ? $obj_files[0]:b.exe : $c_files[0]:b.exe
		end

		if (NTVersion >= 404) then

			set linker = link32
			set stdlibs = libcmt.lib ntdll.lib kernel32.lib

		else

			#	Figure out where libcmt.lib lives on the LIB path.
			if (LIB =~ "*;*") then
				foreach i ($LIB:gs/;/ /)
					if (-e $i\libcmt.lib) then
						@ ldir = i
						break;
					else
						if (CPU == "ALPHA" && -e $i\alpha\libcmt.lib) then
							set ldir = $i\alpha
						end
					end
				end
			else
				@ ldir = LIB
			end

			set linker = coff -link

			if (CPU == "ALPHA") then
				set stdlibs = $ldir\libcmt.lib $ldir\ntdll.lib $ldir\kernel32.lib
			else
				set stdlibs = $ldir\libcmt.lib $ldir\^*.lib
			end
		end

		#	Run the link step, assuming it's a console app with debug info.
		echo $linker -subsystem:console -entry:mainCRTStartup -debug:full	^
			-debugtype:both -out:$exe $obj_files $lib_files "$stdlibs"
		$linker -subsystem:console -entry:mainCRTStartup -debug:full		^
			-debugtype:both -out:$exe $obj_files $lib_files $stdlibs
	end) | ferr
end

cl $argv
